package okl.lab.components.tests
{
	import flash.utils.Dictionary;
	
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.elements.LinkElement;
	
	import mx.events.FlexEvent;
	
	import okl.lab.components.SpellChecker;
	import okl.lab.components.events.SpellCheckEvent;
	import okl.lab.components.interfaces.ISpellChecker;
	
	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertFalse;
	import org.flexunit.asserts.assertTrue;
	import org.flexunit.asserts.fail;
	import org.flexunit.async.Async;
	import org.fluint.uiImpersonation.UIImpersonator;

	/**
	 * SpellChecker ui component test.
	 * 
	 * @see  okl.lab.comonents.SpellChecker
	 * @see  okl.lab.comonents.interfaces.ISpellChecker
	 */
	public class SpellCheckerTest
	{		
		private var spellChecker:ISpellChecker;
		private var suggestions:Dictionary;
		private var inputTexts:Array;
		[Before(async, ui)]
		public function setUp():void
		{
			//data
			inputTexts = [
			 "It's beaotifull day in Laeondon",
			 "It's nice weather",
			 "Parsliy is an apllication frimework for Flex/Flash/AIR applications written in AS3."
			];
			
			var oSuggestions:Object = {
				"beaotifull": ["beautifully", "beautiful", "beautifuler"],
				"Laeondon": ["London", "london", "LONDON", "Londoner"]
			};
			
			suggestions = new Dictionary();
			for(var prop:String in oSuggestions){
				suggestions[prop]=oSuggestions[prop];
			}
			
			spellChecker = new SpellChecker();
			Async.proceedOnEvent(this, spellChecker, FlexEvent.CREATION_COMPLETE);
			UIImpersonator.addChild(spellChecker as SpellChecker);
			
		}
		
		[After(async, ui)]
		public function tearDown():void
		{
			spellChecker.wordCheckFunction=null;
			spellChecker=null;
			inputTexts=null;
			suggestions=null;
			UIImpersonator.removeAllChildren();
			
		}
		
		[Test(async, ui)]
		public function testText():void{
			spellChecker.text = inputTexts[0];
			assertEquals(inputTexts[0], spellChecker.text);
			spellChecker.text = inputTexts[1];
			assertEquals(inputTexts[1], spellChecker.text);
		}
		
		/**
		 * we need to have _spellingSuggestions or custom wordCheckFunction to check
		 */
		[Test]
		public function testCheckWithoutSuggestionsAndWordCheckFunction():void{
			spellChecker.wordCheckFunction =null
			spellChecker.spellingSuggestions=null;
			try{
				spellChecker.check();
				fail();
			}catch(err:Error){};			
		}
		
		/**
		 *_spellingSuggestions not set
		 */
		[Test]
		public function testCheckWithoutSuggestionsAndDefaultCheckFunction():void{
			try{
				spellChecker.check();
				fail();
			}catch(err:Error){};			
		}
		
		[Test(async,ui)]
		public function testCheckSuggestionsFound():void{
			spellChecker.spellingSuggestions=suggestions;
			
			spellChecker.text = inputTexts[0];		
			var expected:Array=["beaotifull", "Laeondon"];
			Async.handleEvent(this, spellChecker, SpellCheckEvent.COMPLETE, onCheckSuggestions, 500, expected, handleTimeout);
			spellChecker.check();
		}
		
		[Test(async,ui)]
		public function testCheckSuggestionsNotFound():void{
			spellChecker.spellingSuggestions=suggestions;
			
			spellChecker.text = inputTexts[1];		
			var expected:Array=[];
			Async.handleEvent(this, spellChecker, SpellCheckEvent.COMPLETE, onCheckSuggestions, 500, expected, handleTimeout);
			spellChecker.check();
		}
		
		[Test(async,ui)]
		public function testCustomSpellFunctionFound():void{
			spellChecker.wordCheckFunction=customSpellCheckFunction;			
			spellChecker.text = inputTexts[2];		
			var expected:Array=["Parsliy", "apllication", "frimework"];
			Async.handleEvent(this, spellChecker, SpellCheckEvent.COMPLETE, onCheckSuggestions, 500, expected, handleTimeout);
			spellChecker.check();
		}
			
		[Test(async,ui)]
		public function testCustomSpellFunctionNotFound():void{
			spellChecker.wordCheckFunction=customSpellCheckFunction;			
			spellChecker.text = inputTexts[0];		
			var expected:Array=[];
			Async.handleEvent(this, spellChecker, SpellCheckEvent.COMPLETE, onCheckSuggestions, 500, expected, handleTimeout);
			spellChecker.check();
		}

	
		
		//{region UTILS
		/**
		 * Mock data for SpellChecker#wordCheckFunction
		 */
		private function customSpellCheckFunction(word:String):Array{
			switch(word){
				case "Parsliy":
					return ["Parsley", "RL", "Mate", "Swiz", "Cairngorm"];
				case "frimework":
					return ["frame", "friends", "framework"];
				case "apllication":
					return ["application", "apple"];
				default:
					return null;
			}
		}
		
		//{region ASYNC_CALLBACKS
		private function onCheckSuggestions(event:SpellCheckEvent, mWords:Array):void{
			var renderers:Array = event.misspelledWordsRenderers;
			assertTrue(mWords.length==renderers.length);
			for(var i:uint; i< mWords.length; i++){
				assertEquals(mWords[i], (renderers[i] as LinkElement).href); //?breaks encapsulation
			}
		}
		
		
		protected function handleTimeout( event:Object ):void
		{
			fail("Event Timeout");
		}
		//}endregion
		
	}
}